package br.com.db;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

import org.apache.sanselan.ImageReadException;
import org.apache.sanselan.ImageWriteException;
import org.apache.sanselan.common.byteSources.ByteSource;
import org.apache.sanselan.common.byteSources.ByteSourceFile;
import org.apache.sanselan.formats.jpeg.JpegImageParser;
import org.apache.sanselan.formats.jpeg.JpegPhotoshopMetadata;
import org.apache.sanselan.formats.jpeg.iptc.IPTCConstants;
import org.apache.sanselan.formats.jpeg.iptc.IPTCRecord;
import org.apache.sanselan.formats.jpeg.iptc.JpegIptcRewriter;
import org.apache.sanselan.formats.jpeg.iptc.PhotoshopApp13Data;

public class PhotoIPTC {

	private File file;
	private ByteSource byteSource;
	private JpegPhotoshopMetadata metadata;

	public PhotoIPTC(String path) throws ImageReadException, IOException {
		this(new File(path));
	}

	public PhotoIPTC(File photoFile) throws ImageReadException, IOException {
		this.file = photoFile;
		byteSource = new ByteSourceFile(file);
		metadata = getMetadata();
	}

	private JpegPhotoshopMetadata getMetadata() throws ImageReadException,
			IOException {
		JpegPhotoshopMetadata photoshopMetadata = new JpegImageParser().getPhotoshopMetadata(byteSource, null);
		if (photoshopMetadata == null) {
			return new JpegPhotoshopMetadata(new PhotoshopApp13Data(new ArrayList(), new ArrayList()));
		}
		return photoshopMetadata;
	}

	public void addIPTCKeyword(ArrayList<String> newKeywords) throws ImageReadException,
			IOException {

		try {
			
			List<IPTCRecord> newIPTCRecords = updateIPTCKeywordsCollection(newKeywords);
			byte[] byteArray;
			byteArray = updateIPTCData(newIPTCRecords);
			updateFileData(byteArray);

		} catch (ImageWriteException e) {
			System.out.println("problem in file: " + this.file.getName());
			//e.printStackTrace();
		}
	}

	private List<IPTCRecord> updateIPTCKeywordsCollection(ArrayList<String> newKeywords) {
		PhotoshopApp13Data photoshopApp13Data = metadata.photoshopApp13Data;

		List<IPTCRecord> iptcRecords = photoshopApp13Data.getRecords();

		for (int i=0; i < newKeywords.size(); i++) {
			iptcRecords.add(new IPTCRecord(IPTCConstants.IPTC_TYPE_KEYWORDS, newKeywords.get(i)));
		}
		return iptcRecords;
	}
	
	public List<String> getIPTCKeyWords(){
		
		List<IPTCRecord> iptcRecords = metadata.photoshopApp13Data.getRecords();		

		List<String> keyWords = new ArrayList<String>();
		
		for (IPTCRecord iptcRecord : iptcRecords) {
			keyWords.add(iptcRecord.getValue());
		}
		
		return keyWords;
	}
	
	public void clearIPTCKeyWords() throws ImageReadException, ImageWriteException, IOException{
		
		//List<IPTCRecord> iptcRecords = metadata.photoshopApp13Data.getRecords();
		
		PhotoshopApp13Data newImageData = new PhotoshopApp13Data(new ArrayList<IPTCRecord>(), metadata.photoshopApp13Data.getNonIptcBlocks());

		ByteArrayOutputStream newDataBAOS = new ByteArrayOutputStream();
		new JpegIptcRewriter().writeIPTC(byteSource, newDataBAOS, newImageData);
		
		updateFileData(newDataBAOS.toByteArray());
	}

	private byte[] updateIPTCData(List<IPTCRecord> iptcRecords)	throws ImageReadException, IOException, ImageWriteException {
		PhotoshopApp13Data newImageData = new PhotoshopApp13Data(iptcRecords, metadata.photoshopApp13Data.getNonIptcBlocks());

		ByteArrayOutputStream newDataBAOS = new ByteArrayOutputStream();
		new JpegIptcRewriter().writeIPTC(byteSource, newDataBAOS, newImageData);

		return newDataBAOS.toByteArray();
	}

	private void updateFileData(byte[] byteArray) throws FileNotFoundException,
			IOException {
		FileOutputStream fileOutputStream = new FileOutputStream(file);
		fileOutputStream.write(byteArray);
		fileOutputStream.flush();
		fileOutputStream.close();
	}

	
	public File getFile() {
		return file;
	}

	public void setFile(File file) {
		this.file = file;
	}

//	private HashSet<String> extractIPTCKeywords(List<IPTCRecord> iptcRecords) {
//		HashSet<String> keywords = new HashSet<String>();
//		for (IPTCRecord iptcRecord : iptcRecords) {
//			keywords.add(iptcRecord.getValue());
//		}
//		return keywords;
//	}

//	public Set<String> getIPTCKeywords() throws ImageReadException, IOException {
	//
//			List<IPTCRecord> iptcRecords = metadata.photoshopApp13Data.getRecords();
	//
//			HashSet<String> keywords = extractIPTCKeywords(iptcRecords);
	//
//			return keywords;
//		}
}
